/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entidade.controller.JSF;

import entidade.controller.JPA.CompraJpaController;
import entidade.controller.JPA.EntradaSaidaJpaController;
import entidade.controller.JPA.ProdutoCompraJpaController;
import entidade.controller.JPA.ProdutoJpaController;
import entidade.controller.JSF.util.PagingInfo;
import entidade.persistencia.Compra;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import javax.faces.FacesException;
import entidade.controller.JSF.util.JsfUtil;
import entidade.controller.JPA.exceptions.NonexistentEntityException;
import entidade.controller.JPA.exceptions.IllegalOrphanException;
import entidade.controller.JSF.util.DateComponentHelper;
import entidade.persistencia.EntradaSaida;
import entidade.persistencia.Produto;
import entidade.persistencia.ProdutoCompra;
import entidade.persistencia.ProdutoVenda;
import entidade.persistencia.Venda;
import entidade.vo.ParcelaVO;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

/**
 *
 * @author victorinox
 */
public class CompraController {

    public CompraController() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        jpaController = (CompraJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "compraJpa");
        pagingInfo = new PagingInfo();
        converter = new CompraConverter();
    }
    private Compra compra = null;
    private List<Compra> compraItems = null;
    private CompraJpaController jpaController = null;
    private CompraConverter converter = null;
    private PagingInfo pagingInfo = null;
    private List<ParcelaVO> parcelaVenda = null;
    private Boolean isEditingVenda = false;
    private Integer qtdParcelas = 1;
    private DateComponentHelper dateCompra = new DateComponentHelper(new Date());
    private DateComponentHelper dateEntrega = new DateComponentHelper(new Date());

    public PagingInfo getPagingInfo() {
        pagingInfo.setItemCount(10);
        pagingInfo.setBatchSize(10);
        if (pagingInfo.getItemCount() == -1) {
            pagingInfo.setItemCount(jpaController.getCompraCount());
        }
        return pagingInfo;
    }

    public SelectItem[] getCompraItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(jpaController.findCompraEntities(), false);
    }

    public SelectItem[] getCompraItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(jpaController.findCompraEntities(), true);
    }

    public Compra getCompra() {
        if (compra == null) {
            compra = (Compra) JsfUtil.getObjectFromRequestParameter("jsfcrud.currentCompra", converter, null);
        }
        if (compra == null) {
            compra = new Compra();
        }
        return compra;
    }

    public String listSetup() {
        reset(true);
        return "compra_list";
    }

    public String createSetup() {
        reset(false);
        compra = new Compra();
        return "compra_create";
    }

    public String create() {

        List<ProdutoCompra> pvs = compra.getProdutoCompraCollection();
        compra.setProdutoCompraCollection(null);

        try {
            jpaController.create(compra);
            
            FacesContext facesContext = FacesContext.getCurrentInstance();
            ProdutoCompraJpaController prodCompraController = (ProdutoCompraJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "produtoCompraJpa");
            for (int i = 0; i < pvs.size(); i++) {
                ProdutoCompra prodCompra = pvs.get(i);

                Produto prod = prodCompra.getProduto();
                prod.setQuantidadeEstoque(prod.getQuantidadeEstoque() - prodCompra.getQuantidade());

                ProdutoJpaController prodController = (ProdutoJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "produtoJpa");
                prodController.edit(prod);

                prodCompra.setCompra(compra);
                prodCompraController.create(prodCompra);
            }

            List<EntradaSaida> entradaSaidaList = new ArrayList<EntradaSaida>();
            EntradaSaidaJpaController entradaSaidaController = (EntradaSaidaJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "entradaSaidaJpa");
            List<Compra> comprasTemp = new ArrayList<Compra>();
            comprasTemp.add(compra);
            for (int i = 0; i < parcelaVenda.size(); i++) {
                ParcelaVO parcVenda = parcelaVenda.get(i);
                EntradaSaida entradaSaida = new EntradaSaida();
                entradaSaida.setDataOperacao(compra.getDataCompra());
                entradaSaida.setDataVencimento(parcVenda.getDataParcela());
                entradaSaida.setParcelaAtual(parcVenda.getNumeroParcela());
                entradaSaida.setQuantidadeParcela(parcVenda.getTotParcelas());
                Float preco = parcVenda.getValorParcela();
                preco = preco * (-1);
                entradaSaida.setValor(preco);
                entradaSaida.setCompraCollection(comprasTemp);
                entradaSaidaController.create(entradaSaida);
                entradaSaidaList.add(entradaSaida);
            }

            parcelaVenda = null;
            compra.setJurosMes(0f);
            qtdParcelas = 1;

            setIsEditingVenda(false);

            JsfUtil.addSuccessMessage("Compra was successfully created.");
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }
        return listSetup();
    }

    public String detailSetup() {
        return scalarSetup("compra_detail");
    }

    public String editSetup() {
        return scalarSetup("compra_edit");
    }

    public String voltarCompraSetup() {
        return "compra_create";
    }

    public void calcularParcelas_txtJurosMes(ValueChangeEvent evt) {


        if (evt.getNewValue() instanceof Long) {
            Long l = (Long) evt.getNewValue();
            compra.setJurosMes(new Float(l.floatValue()));
        } else if(evt.getNewValue() instanceof Double) {
            Double l = (Double) evt.getNewValue();
            compra.setJurosMes(l.floatValue());
        }else{
            compra.setJurosMes((Float) evt.getNewValue());
        }
        calcularParcelas();
    }

    public void calcularParcelas_txtQtdParcelas(ValueChangeEvent evt) {
        setQtdParcelas((Integer) evt.getNewValue());
        calcularParcelas();
    }

    public String calcularParcelas() {
        List<ProdutoCompra> produtosCompras = compra.getProdutoCompraCollection();

        compra.setTotalCompra(0f);

        if (produtosCompras == null || produtosCompras.size() == 0) {
            return "";
        }

        for (int i = 0; i < produtosCompras.size(); i++) {
            ProdutoCompra produtoCompra = produtosCompras.get(i);
            compra.setTotalCompra(compra.getTotalCompra() + produtoCompra.getPrecoUnitario() * produtoCompra.getQuantidade());
        }

        compra.setTotalCompra(compra.getTotalCompra() + compra.getValorTransporte());
        compra.setTotalCompra(compra.getTotalCompra() + compra.getSeguroTransporte());

        float totalParcela = compra.getTotalCompra() / getQtdParcelas();
        if (compra.getJurosMes() > 0f && getQtdParcelas() > 1) {
            totalParcela += totalParcela * compra.getJurosMes() / 10;
        }

        compra.setTotalCompra(totalParcela * getQtdParcelas());

        parcelaVenda = new ArrayList<ParcelaVO>();

        Calendar cal = Calendar.getInstance();
        cal.setTime(compra.getDataCompra());
        for (int i = 1; i <= getQtdParcelas(); i++) {
            if (i > 1) {
                cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1);
            }
            parcelaVenda.add(new ParcelaVO(i, totalParcela, cal.getTime(), getQtdParcelas()));
        }
        return "";
    }

    public String removerProdutoCompra() {
        String prodId = JsfUtil.getRequestParameter("jsfcrud.currentProduto");
        int prod = Integer.parseInt(prodId);

        List<ProdutoCompra> prodsCompra = compra.getProdutoCompraCollection();
        List<ProdutoCompra> prodsCompraNew = new ArrayList<ProdutoCompra>();
        for (int i = 0; i < prodsCompra.size(); i++) {
            ProdutoCompra produtoCompra = prodsCompra.get(i);
            if (produtoCompra.getProduto().getProdutoId().intValue() != prod) {
                prodsCompraNew.add(produtoCompra);
            }
        }
        if (prodsCompraNew.size() == 0) {
            prodsCompraNew = null;
            setParcelaVenda(null);
            compra.setJurosMes(0f);
            setQtdParcelas((Integer) 1);

        }
        compra.setProdutoCompraCollection(prodsCompraNew);
        calcularParcelas();
        return "compra_create";
    }

    private String scalarSetup(String destination) {
        reset(false);
        compra = (Compra) JsfUtil.getObjectFromRequestParameter("jsfcrud.currentCompra", converter, null);
        if (compra == null) {
            String requestCompraString = JsfUtil.getRequestParameter("jsfcrud.currentCompra");
            JsfUtil.addErrorMessage("The compra with id " + requestCompraString + " no longer exists.");
            return relatedOrListOutcome();
        }
        return destination;
    }

    public String edit() {
        String compraString = converter.getAsString(FacesContext.getCurrentInstance(), null, compra);
        String currentCompraString = JsfUtil.getRequestParameter("jsfcrud.currentCompra");
        if (compraString == null || compraString.length() == 0 || !compraString.equals(currentCompraString)) {
            String outcome = editSetup();
            if ("compra_edit".equals(outcome)) {
                JsfUtil.addErrorMessage("Could not edit compra. Try again.");
            }
            return outcome;
        }
        try {
            jpaController.edit(compra);
            JsfUtil.addSuccessMessage("Compra was successfully updated.");
        } catch (IllegalOrphanException oe) {
            JsfUtil.addErrorMessages(oe.getMessages());
            return null;
        } catch (NonexistentEntityException ne) {
            JsfUtil.addErrorMessage(ne.getLocalizedMessage());
            return listSetup();
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }
        return detailSetup();
    }

    public String destroy() {
        String idAsString = JsfUtil.getRequestParameter("jsfcrud.currentCompra");
        Integer id = new Integer(idAsString);
        try {
            jpaController.destroy(id);
            JsfUtil.addSuccessMessage("Compra was successfully deleted.");
        } catch (IllegalOrphanException oe) {
            JsfUtil.addErrorMessages(oe.getMessages());
            return null;
        } catch (NonexistentEntityException ne) {
            JsfUtil.addErrorMessage(ne.getLocalizedMessage());
            return relatedOrListOutcome();
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }
        return relatedOrListOutcome();
    }

    private String relatedOrListOutcome() {
        String relatedControllerOutcome = relatedControllerOutcome();
        if (relatedControllerOutcome != null) {
            return relatedControllerOutcome;
        }
        return listSetup();
    }

    public List<Compra> getCompraItems() {
        if (compraItems == null) {
            getPagingInfo();
            compraItems = jpaController.findCompraEntities(pagingInfo.getBatchSize(), pagingInfo.getFirstItem());
        }
        return compraItems;
    }

    public String next() {
        reset(false);
        getPagingInfo().nextPage();
        return "compra_list";
    }

    public String prev() {
        reset(false);
        getPagingInfo().previousPage();
        return "compra_list";
    }

    private String relatedControllerOutcome() {
        String relatedControllerString = JsfUtil.getRequestParameter("jsfcrud.relatedController");
        String relatedControllerTypeString = JsfUtil.getRequestParameter("jsfcrud.relatedControllerType");
        if (relatedControllerString != null && relatedControllerTypeString != null) {
            FacesContext context = FacesContext.getCurrentInstance();
            Object relatedController = context.getApplication().getELResolver().getValue(context.getELContext(), null, relatedControllerString);
            try {
                Class<?> relatedControllerType = Class.forName(relatedControllerTypeString);
                Method detailSetupMethod = relatedControllerType.getMethod("detailSetup");
                return (String) detailSetupMethod.invoke(relatedController);
            } catch (ClassNotFoundException e) {
                throw new FacesException(e);
            } catch (NoSuchMethodException e) {
                throw new FacesException(e);
            } catch (IllegalAccessException e) {
                throw new FacesException(e);
            } catch (InvocationTargetException e) {
                throw new FacesException(e);
            }
        }
        return null;
    }

    private void reset(boolean resetFirstItem) {
        compra = null;
        compraItems = null;
        pagingInfo.setItemCount(-1);
        if (resetFirstItem) {
            pagingInfo.setFirstItem(0);
        }
    }

    public void validateCreate(FacesContext facesContext, UIComponent component, Object value) {
        Compra newCompra = new Compra();
        String newCompraString = converter.getAsString(FacesContext.getCurrentInstance(), null, newCompra);
        String compraString = converter.getAsString(FacesContext.getCurrentInstance(), null, compra);
        if (!newCompraString.equals(compraString)) {
            createSetup();
        }
    }

    public Converter getConverter() {
        return converter;
    }

    /**
     * @return the parcelaVenda
     */
    public List<ParcelaVO> getParcelaVenda() {
        return parcelaVenda;
    }

    /**
     * @param parcelaVenda the parcelaVenda to set
     */
    public void setParcelaVenda(List<ParcelaVO> parcelaVenda) {
        this.parcelaVenda = parcelaVenda;
    }

    /**
     * @return the isEditingVenda
     */
    public Boolean getIsEditingVenda() {
        return isEditingVenda;
    }

    /**
     * @param isEditingVenda the isEditingVenda to set
     */
    public void setIsEditingVenda(Boolean isEditingVenda) {
        this.isEditingVenda = isEditingVenda;
    }

    /**
     * @return the qtdParcelas
     */
    public Integer getQtdParcelas() {
        return qtdParcelas;
    }

    /**
     * @param qtdParcelas the qtdParcelas to set
     */
    public void setQtdParcelas(Integer qtdParcelas) {
        this.qtdParcelas = qtdParcelas;
    }

    /**
     * @return the dateCompra
     */
    public DateComponentHelper getDateCompra() {
        return dateCompra;
    }

    /**
     * @param dateCompra the dateCompra to set
     */
    public void setDateCompra(DateComponentHelper dateCompra) {
        this.dateCompra = dateCompra;
    }

    /**
     * @return the dateEntrega
     */
    public DateComponentHelper getDateEntrega() {
        return dateEntrega;
    }

    /**
     * @param dateEntrega the dateEntrega to set
     */
    public void setDateEntrega(DateComponentHelper dateEntrega) {
        this.dateEntrega = dateEntrega;
    }
}
